00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #ifndef DEPROFILE_HPP
00033 #define DEPROFILE_HPP
00034
00035 #include "deGlobalTypes.hpp"
00036
00037 #if defined(DEUTIL_DLL_EXPORTS) || defined(DESTINY3D_EXPORT_ALL)
00038 # define DEPROFILE_API extern "C" DEDLL_EXPORT
00039 #elif defined(DESTINY3D_STATIC_LINK)
00040 # define DEPROFILE_API extern "C"
00041 #else
00042 # define DEPROFILE_API extern "C" DEDLL_IMPORT
00043 #endif
00044
00045 #ifdef USING_DESTINY3D
00046 #ifdef _DEBUG
00047 # ifdef DESTINY3D_STATIC_LINK
00048 # pragma comment(lib, "deUtil_sd")
00049 # else
00050 # pragma comment(lib, "deUtild")
00051 # endif //DESTINY3D_STATIC_LINK
00052 #else
00053 # ifdef DESTINY3D_STATIC_LINK
00054 # pragma comment(lib, "deUtil_s")
00055 # else
00056 # pragma comment(lib, "deUtil")
00057 # endif //DESTINY3D_STATIC_LINK
00058 #endif //_DEBUG
00059 #endif //USING_DESTINY3D
00060
00061 static inline void GrabTSC(u64 * Clock)
00062 {
00063 #ifdef __GNUC__
00064 __asm__ __volatile__ ( \
00065 "rdtsc\n\t" \
00066 : "=A" (Clock));
00067 #else
00068 _asm
00069 {
00070 RDTSC
00071 mov ecx, Clock
00072 mov [ecx], eax
00073 mov [ecx+4],edx
00074 }
00075 #endif
00076 }
00077
00078 class deProfile;
00079 class IdeProfileManager;
00080
00081
00082 DEPROFILE_API IdeProfileManager* IdeProfile_GetTheManager();
00083 DEPROFILE_API void IdeProfile_ShutDown();
00084
00085
00086 DE3D_INTERFACE_(IdeProfileManager)
00087 {
00088 public:
00089 virtual void StartProfile(deProfile * profile) = 0;
00090 virtual deBoolean RecordInfo(deProfile * profile) = 0;
00091 virtual long GrabIDNum() = 0;
00092 virtual long EstimateFrequency() = 0;
00093 virtual s64 TimeSpentIn(char * ProfileName, long IDNum = 0) = 0;
00094 virtual s64 TimeSpentIn_IDByName(char * Name) = 0;
00095 virtual const char* EndFrame(deBoolean OutputString) = 0;
00096 virtual void ResetStats() = 0;
00097 };
00098
00099
00100
00101 class deProfile
00102 {
00103 public:
00104 friend class deProfileManager;
00105
00106 inline deProfile::deProfile(char * ProfileName)
00107 {
00108 if (!ProfileName)
00109 throw "You must specify a name";
00110 TheManager = IdeProfile_GetTheManager();
00111 strncpy(m_ProfileInfo.IDName, ProfileName, 127);
00112 m_ProfileInfo.IDName[127] = '\0';
00113 m_ProfileInfo.IDNum = 0;
00114 TheManager->StartProfile(this);
00115 }
00116
00117 inline deProfile::deProfile(long * ProfileIDNum)
00118 {
00119
00120
00121 TheManager = IdeProfile_GetTheManager();
00122 if (*ProfileIDNum)
00123 {
00124 m_ProfileInfo.IDNum = *ProfileIDNum;
00125 }
00126 else
00127 {
00128 m_ProfileInfo.IDNum = TheManager->GrabIDNum();
00129 *ProfileIDNum = m_ProfileInfo.IDNum;
00130 }
00131 m_ProfileInfo.IDName[0] = '\0';
00132 TheManager->StartProfile(this);
00133 }
00134
00135 inline deProfile::deProfile(long * ProfileIDNum, char * ProfileName)
00136 {
00137 TheManager = IdeProfile_GetTheManager();
00138 if (*ProfileIDNum)
00139 {
00140 m_ProfileInfo.IDNum = *ProfileIDNum;
00141 }
00142 else
00143 {
00144 m_ProfileInfo.IDNum = TheManager->GrabIDNum();
00145 *ProfileIDNum = m_ProfileInfo.IDNum;
00146 }
00147
00148 if (!ProfileName)
00149 throw;
00150 strncpy(m_ProfileInfo.IDName, ProfileName, 127);
00151 m_ProfileInfo.IDName[127] = '\0';
00152 TheManager->StartProfile(this);
00153 }
00154
00155 inline deProfile::~deProfile()
00156 {
00157 TheManager->RecordInfo(this);
00158 }
00159
00160 private:
00161 struct ProfileInfo_t
00162 {
00163 u32 IDNum;
00164 char IDName[128];
00165 } m_ProfileInfo;
00166 IdeProfileManager * TheManager;
00167 };
00168
00169
00170 #ifdef DESTINY3D_PLATFORM_WIN32
00171 # define WIN32_LEAN_AND_MEAN
00172 # include <windows.h>
00173 # include <mmsystem.h>
00174 # pragma comment(lib, "winmm")
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188 class deTimer_QPC
00189 {
00190 s64 m_StartTime;
00191 s64 m_StopTime;
00192 s64 m_Frequency;
00193 public:
00194 inline deTimer_QPC() : m_StartTime(0), m_StopTime(0), m_Frequency(0) {}
00195 inline ~deTimer_QPC() {}
00196 inline void GrabStartTime()
00197 {
00198 if (!QueryPerformanceCounter((LARGE_INTEGER*)&m_StartTime))
00199 throw "QPC Unsupported!";
00200 }
00201 inline void GrabStopTime()
00202 {
00203 if (!QueryPerformanceCounter((LARGE_INTEGER*)&m_StopTime))
00204 throw "QPC Unsupported!";
00205 }
00206 inline double DiffTime()
00207 {
00208 if (m_Frequency == 0)
00209 QueryPerformanceFrequency((LARGE_INTEGER*)&m_Frequency);
00210 double retval = (m_StopTime-m_StartTime)/((double)m_Frequency);
00211 return retval;
00212 }
00213 inline double DiffTime(double maxStep)
00214 {
00215 double retval = DiffTime();
00216 if (maxStep > 0 && retval > maxStep)
00217 retval = maxStep;
00218 return retval;
00219 }
00220 };
00221
00222 class deTimer_TGT
00223 {
00224 u32 m_StartTime;
00225 u32 m_StopTime;
00226 public:
00227 inline deTimer_TGT() : m_StartTime(0), m_StopTime(0) {}
00228 inline ~deTimer_TGT() {}
00229 inline void GrabStartTime()
00230 {
00231 timeBeginPeriod(1);
00232 m_StartTime = timeGetTime();
00233 timeEndPeriod(1);
00234 }
00235 inline void GrabStopTime()
00236 {
00237 timeBeginPeriod(1);
00238 m_StopTime = timeGetTime();
00239 timeEndPeriod(1);
00240 }
00241 inline double DiffTime()
00242 {
00243 double retval = (m_StopTime-m_StartTime)/1000.0;
00244 return retval;
00245 }
00246 inline double DiffTime(double maxStep)
00247 {
00248 double retval = DiffTime();
00249 if (maxStep > 0 && retval > maxStep)
00250 retval = maxStep;
00251 return retval;
00252 }
00253 };
00254 #else // DESTINY3D_PLATFORM_WIN32
00255 # pragma note(Unsupported platform for QPC and TGT timer - deferring to TSC)
00256 # define DE3D_TIMER_TSC
00257 #endif // DESTINY3D_PLATFORM_WIN32
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267 class deTimer_TSC
00268 {
00269 u64 m_StartTime;
00270 u64 m_StopTime;
00271 double m_CPU_Hz;
00272 public:
00273 inline deTimer_TSC() : m_StartTime(0), m_StopTime(0), m_CPU_Hz(0.0) {}
00274 inline ~deTimer_TSC() {}
00275 inline void GrabStartTime()
00276 { GrabTSC(&m_StartTime); }
00277 inline void GrabStopTime()
00278 { GrabTSC(&m_StopTime); }
00279 inline double DiffTime()
00280 {
00281 if (m_CPU_Hz == 0.0)
00282 m_CPU_Hz = 1000000.0 * IdeProfile_GetTheManager()->EstimateFrequency();
00283 double retval = (m_StopTime-m_StartTime)/m_CPU_Hz;
00284 return retval;
00285 }
00286 inline double DiffTime(double maxStep)
00287 {
00288 double retval = DiffTime();
00289 if (maxStep > 0 && retval > maxStep)
00290 retval = maxStep;
00291 return retval;
00292 }
00293 };
00294
00295
00296
00297 #define DE3D_TIMER_QPC
00298
00299
00300 #if defined(DE3D_TIMER_TSC)
00301 typedef deTimer_TSC deTimer;
00302 #elif defined(DE3D_TIMER_QPC)
00303 typedef deTimer_QPC deTimer;
00304 #elif defined(DE3D_TIMER_TGT)
00305 typedef deTimer_TGT deTimer;
00306 #endif // DE3D_TIMER_QPC
00307
00308 #undef DE3D_TIMER_TSC
00309 #undef DE3D_TIMER_QPC
00310 #undef DE3D_TIMER_TGT
00311
00312 #define PROFILE_RELEASE_ALSO
00313
00314 #if defined(_DEBUG) || defined(PROFILE_RELEASE_ALSO)
00315 #define PROFILE(ProfileID) deProfile Profile_Identifier___(ProfileID)
00316 #define PROFILE_ID_NAME(ProfileID,Name) deProfile Profile_Identifier___(ProfileID,Name)
00317 #else
00318 #define PROFILE(ProfileID)
00319 #define PROFILE_ID_NAME(ProfileID,Name)
00320 #endif
00321
00322
00323 #endif